import React, { Component } from 'react';
import {
  CloseOutlined,
  VerticalAlignBottomOutlined,
  SwapOutlined,
  RedoOutlined,
  UndoOutlined,
  ZoomOutOutlined,
  ZoomInOutlined,
  RightOutlined,
  LeftOutlined
} from '@ant-design/icons';
import './index.less';
import AuthImg from '../AuthImg/AuthImg';

/**
 * 图片预览组件
 * @author liu_jshan
 * @version 1.1 20240421
 */
class ImagePreviewMasked extends Component {
  constructor(props) {
    super(props);
    this.imageRef = React.createRef(); // 创建图片引用，用于操作DOM元素
    this.state = {
      scaleX: 1, // 水平翻转状态，默认不翻转
      scaleY: 1, // 垂直翻转状态，默认不翻转
      rotate: 0, // 图片旋转角度，默认不旋转
      position: { left: null, top: null, right: null, bottom: null }, // 图片位置状态，默认无偏移
      imageArray: [], // 存储图片数组
      currentIndex: 0, // 当前显示的图片索引
      isShow: true // 控制图片是否显示，默认显示
    };
  }

  componentDidMount() {
    this.resetImageStyle(); // 初始化时重置图片样式
    const { src, alt, imageArray } = this.props;
    let newImageArray = [];
    let currentIndex = 0;

    // 处理传入的图片数组
    if (imageArray && imageArray.length > 0) {
      newImageArray = [...imageArray];
    }

    // 如果有单张图片源，则处理单张图片
    if (src) {
      const index = this.findIndex(src, newImageArray); // 查找图片在数组中的索引
      if (index > -1) {
        currentIndex = index; // 如果找到则设置当前索引
      } else {
        newImageArray.push({
          src,
          alt,
        });
        currentIndex = newImageArray.length - 1; // 如果未找到则添加到数组末尾并设置为当前索引
      }
    }

    this.setState({
      imageArray: newImageArray,
      currentIndex
    });
  }

  findIndex = (src, imageArray) => {
    for (let i = 0; i < imageArray.length; i++) {
      if (imageArray[i].src === src) {
        return i; // 返回图片在数组中的索引
      }
    }
    return -1; // 如果未找到返回-1
  }

  componentDidUpdate(prevProps) {
    // 如果视觉属性变化且为true，则重置图片样式并更新当前图片索引
    if (prevProps.visual !== this.props.visual && this.props.visual) {
      this.resetImageStyle();

      const index = this.findIndex(this.props.src, this.state.imageArray);
      if (index > -1) {
        this.setState({
          currentIndex: index
        });
      }

      // 控制样式变化，实现动画过渡效果
      this.setState({
        isShow: false
      });
      setTimeout(() => {
        this.setState({
          isShow: true
        });
      }, 10);
    }
    if (prevProps.imageArray && this.props.imageArray && prevProps.imageArray.length !== this.props.imageArray.length) {
      const index = this.findIndex(this.props.src, this.state.imageArray);
      this.setState({
        imageArray: [...this.props.imageArray],
        currentIndex: index !== -1 ? index : 0
      });
    }
  }

  resetImageStyle() {
    this.setState({
      scaleX: 1, // 重置水平翻转状态
      scaleY: 1, // 重置垂直翻转状态
      rotate: 0, // 重置旋转角度
      position: { left: null, top: null, right: null, bottom: null } // 重置位置状态
    });
  }

  handleMouseDown = (e) => {
    e.preventDefault();
    const startX = e.clientX;
    const startY = e.clientY;
    let prevX = e.clientX;
    let prevY = e.clientY;

    const onMouseMove = (e) => {
      const newX = prevX - e.clientX;
      const newY = prevY - e.clientY;
      let left = e.target.offsetLeft - newX;
      let top = e.target.offsetTop - newY;
      let right = null;
      let bottom = null;
      this.setState({ position: { left, top, right, bottom } }); // 更新图片位置
      prevX = e.clientX;
      prevY = e.clientY;
    };

    const onMouseUp = (e) => {
      let left = null;
      let top = null;
      let right = null;
      let bottom = null;
      const changeWidth = Math.abs(this.imageRef.current.clientWidth * this.state.scaleX); // 放大缩小后的宽度
      const changeHeight = Math.abs(this.imageRef.current.clientHeight * this.state.scaleY); // 放大缩小后的高度

      // 根据拖动方向调整图片位置
      if (changeWidth > window.innerWidth) {
        if (prevX > startX) {
          left = (changeWidth - e.target.clientWidth) / 2;
        } else if (prevX < startX) right = (changeWidth - e.target.clientWidth) / 2;
      }
      if (changeHeight > window.innerHeight) {
        if (prevY > startY) {
          top = (changeHeight - e.target.clientHeight) / 2;
        } else if (prevY < startY) bottom = (changeHeight - e.target.clientHeight) / 2;
      }
      this.setState({ position: { left, top, right, bottom } });
      document.removeEventListener('mousemove', onMouseMove);
      document.removeEventListener('mouseup', onMouseUp);
    };

    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', onMouseUp);
  };

  onDownload = () => {
    fetch(this.props.src)
      .then((response) => response.blob())
      .then((blob) => {
        const namUrl = this.props.src.split('/');
        const url = URL.createObjectURL(new Blob([blob]));
        const link = document.createElement('a');
        link.href = url;
        link.download = namUrl[namUrl.length - 1]; // 设置下载文件名
        document.body.appendChild(link);
        link.click();
        URL.revokeObjectURL(url);
        link.remove();
      });
  };

  flipHorizontally = () => {
    this.setState({ scaleX: -this.state.scaleX }); // 水平翻转图片
  };

  flipVertically = () => {
    this.setState({ scaleY: -this.state.scaleY }); // 垂直翻转图片
  };

  rotateToRight = () => {
    const newRotate = this.state.rotate + 90 === 360 ? 0 : this.state.rotate + 90;
    this.setState({ rotate: newRotate }); // 顺时针旋转90度
  };

  rotateToLeft = () => {
    const newRotate = this.state.rotate - 90 < 0 ? 270 : this.state.rotate - 90;
    this.setState({ rotate: newRotate }); // 逆时针旋转90度
  };

  backPlace = () => {
    const changeWidth = Math.abs(this.imageRef.current.clientWidth * this.state.scaleX); // 放大缩小后的宽度
    const changeHeight = Math.abs(this.imageRef.current.clientHeight * this.state.scaleY); // 放大缩小后的高度
    if (changeWidth < window.innerWidth && changeHeight < window.innerHeight) {
      this.setState({ position: { left: null, top: null, right: null, bottom: null } }); // 如果图片尺寸小于窗口大小，则重置位置
    }
  };

  zoomIn = () => {
    this.setState((prevState) => ({
      scaleX: prevState.scaleX * 1.1 < 5 ? prevState.scaleX * 1.1 : prevState.scaleX, // 放大图片，最大放大倍数为5
      scaleY: prevState.scaleY * 1.1 < 5 ? prevState.scaleY * 1.1 : prevState.scaleY
    }));
    this.backPlace();
  };

  zoomOut = () => {
    this.setState((prevState) => ({
      scaleX: prevState.scaleX / 1.1 > 0.1 ? prevState.scaleX / 1.1 : prevState.scaleX, // 缩小图片，最小缩小倍数为0.1
      scaleY: prevState.scaleY / 1.1 > 0.1 ? prevState.scaleY / 1.1 : prevState.scaleY
    }));
    this.backPlace();
  };

  stopPropagationClick = (callBack) => {
    return (event) => {
      event.stopPropagation();
      if (callBack && typeof callBack === 'function') {
        callBack();
      }
    };
  };

  gotoLeft = () => {
    const { currentIndex } = this.state;
    if (currentIndex > 0) {
      this.resetImageStyle();
      this.setState({ currentIndex: currentIndex - 1 }); // 切换到上一张图片
    }
  }

  gotoRigth = () => {
    const { imageArray, currentIndex } = this.state;
    if (currentIndex < imageArray.length - 1) {
      this.resetImageStyle();
      this.setState({ currentIndex: currentIndex + 1 }); // 切换到下一张图片
    }
  }

  render() {
    const { scaleX, scaleY, rotate, position, imageArray, currentIndex, isShow } = this.state;
    const { visual, onCancel } = this.props;
    if (!visual) return null; // 如果视觉属性为false，则不渲染组件

    return (
      <div className={isShow ? 'ImagePreviewMasked-show' : 'ImagePreviewMasked-none'}>
        <div className='ImagePreviewMasked-closed' onClick={this.stopPropagationClick(async () => {
          if (onCancel && typeof onCancel === 'function') {
            await onCancel();
          }
        })}>
          <CloseOutlined /> {/* 关闭按钮 */}
        </div>

        {currentIndex > 0 && (
          <div className='ImagePreviewMasked-left' onClick={this.stopPropagationClick(this.gotoLeft)}>
            <LeftOutlined /> {/* 左箭头按钮，切换到上一张图片 */}
          </div>
        )}

        <AuthImg
          style={{ transform: `scaleX(${scaleX}) scaleY(${scaleY}) rotate(${rotate}deg)`, ...position }}
          ref={this.imageRef}
          authSrc={imageArray.length > 0 ? imageArray[currentIndex].src : ''}
          alt={imageArray.length > 0 ? imageArray[currentIndex].alt : ''}
          onClick={this.stopPropagationClick()}
          onMouseDown={this.handleMouseDown}
        />

        {currentIndex < imageArray.length - 1 && (
          <div className='ImagePreviewMasked-right' onClick={this.stopPropagationClick(this.gotoRigth)}>
            <RightOutlined /> {/* 右箭头按钮，切换到下一张图片 */}
          </div>
        )}

        <div className='ImagePreviewMasked-utils' onClick={this.stopPropagationClick()}>
          <div className='ImagePreviewMasked-utils-item'>
            <VerticalAlignBottomOutlined onClick={this.onDownload} /> {/* 下载按钮 */}
          </div>
          <div className='ImagePreviewMasked-utils-item'>
            <SwapOutlined onClick={this.flipHorizontally} /> {/* 水平翻转按钮 */}
          </div>
          <div className='ImagePreviewMasked-utils-item'>
            <SwapOutlined style={{ transform: 'rotate(90deg)' }} onClick={this.flipVertically} /> {/* 垂直翻转按钮 */}
          </div>
          <div className='ImagePreviewMasked-utils-item'>
            <RedoOutlined onClick={this.rotateToRight} /> {/* 顺时针旋转按钮 */}
          </div>
          <div className='ImagePreviewMasked-utils-item'>
            <UndoOutlined onClick={this.rotateToLeft} /> {/* 逆时针旋转按钮 */}
          </div>
          <div className='ImagePreviewMasked-utils-item'>
            <ZoomInOutlined onClick={this.zoomIn} /> {/* 放大按钮 */}
          </div>
          <div className='ImagePreviewMasked-utils-item'>
            <ZoomOutOutlined onClick={this.zoomOut} /> {/* 缩小按钮 */}
          </div>
        </div>
      </div>
    );
  }
}

export default ImagePreviewMasked;